package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xuecheng.api.content.model.dto.CourseTeacherDTO;
import com.xuecheng.api.content.model.dto.TeachplanDTO;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.enums.content.CourseModeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.JsonUtil;
import com.xuecheng.content.common.constant.ContentErrorCode;
import com.xuecheng.content.common.util.QiniuUtils;
import com.xuecheng.content.entity.CourseBase;
import com.xuecheng.content.entity.CourseMarket;
import com.xuecheng.content.entity.CoursePub;
import com.xuecheng.content.mapper.CoursePubMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.CoursePubService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程发布 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CoursePubServiceImpl extends ServiceImpl<CoursePubMapper, CoursePub> implements CoursePubService {

    /* spring boot 自动装配已经提供此对象 */
    @Autowired
    private Configuration configuration;

    @Value("${file.qiniu.accessKey}")
    private String accessKey;

    @Value("${file.qiniu.secretKey}")
    private String secretKey;

    @Value("${file.qiniu.bucket}")
    private String bucket;

    @Value("${course.publish.position}")
    private String pagePosition;

    @Autowired
    private CourseBaseService courseBaseService;

    /*
     * 业务分析：
     *   1.判断课程审核状态和课程发布数据（从数据角度来考虑的严谨性）
     *   2.生成课程详情页面（Freemarker）
     *       数据模型
     *       页面模板
     *   3.将生成后的页面上传到七牛云上
     *       使用工具类来完成
     * */
    public void publishPage(Long courseBaseId) {

        //1.判断课程审核状态和课程发布数据（从数据角度来考虑的严谨性）
        CourseBase courseBase = courseBaseService.getById(courseBaseId);
        if (!(CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode().equals(courseBase.getAuditStatus()))) {
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }
        //判断发布数据是否存在
        LambdaQueryWrapper<CoursePub> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CoursePub::getCourseId, courseBaseId);
        CoursePub coursePub = this.getOne(queryWrapper);
        if (ObjectUtils.isEmpty(coursePub)) {
            ExceptionCast.cast(ContentErrorCode.E_120203);
        }

        try {
            //2.生成课程详情页面（Freemarker）
            //数据模型
            Map<String, Object> dataMap = generateDataMap(coursePub);
            //页面模板
            Template template = configuration.getTemplate("learing_article.ftl");

            String strHtml = FreeMarkerTemplateUtils.processTemplateIntoString(template, dataMap);

            //3.将生成后的页面上传到七牛云上
            // 课程详情页：课程发布的Id值+.html
            String pageKey = coursePub.getId() + ".html";

            // pages/xxx.html
            String filePosition = pagePosition + pageKey;
            QiniuUtils.upload2Qiniu(accessKey, secretKey, bucket, strHtml, filePosition);
        } catch (Exception e) {
            ExceptionCast.castWithException(ContentErrorCode.E_120204,e);
        }

        //修改课程发布中的状态is_publish = 0
        LambdaUpdateWrapper<CoursePub> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CoursePub::getIsPub, CoursePub.IS_PUB);
        updateWrapper.set(CoursePub::getChangeDate, LocalDateTime.now());
        updateWrapper.eq(CoursePub::getId, coursePub.getId());

        boolean update = this.update(updateWrapper);
        if (!update) {
            ExceptionCast.cast(ContentErrorCode.E_120204);
        }

    }



    /*
     * 根据CoursePub生成数据模型DataMap数据
     *       根据模板页面里的关键4个key来生成对应数据
     * */
    private Map<String, Object> generateDataMap(CoursePub coursePub) {
        //1.构建数据模型
        Map<String, Object> dataMap = new HashMap();
        //1.课程发布key
        dataMap.put("coursePub", coursePub);

        //2.课程营销key
        String market = coursePub.getMarket();
        CourseMarket courseMarket = JsonUtil.jsonToObject(market, CourseMarket.class);
        dataMap.put("courseMarket", courseMarket);

        //3.课程模式key
        CourseModeEnum[] values = CourseModeEnum.values();
        dataMap.put("courseTeachModeEnums", values);

        //4.课程计划key
        String teachplan = coursePub.getTeachplan();
        TeachplanDTO teachplanDTO = JsonUtil.jsonToObject(teachplan, TeachplanDTO.class);
        dataMap.put("teachplanNode", teachplanDTO);

        //5.课程教师key
        String teachers = coursePub.getTeachers();
        List<CourseTeacherDTO> courseTeacherDTOS = JsonUtil.jsonToList(teachers, CourseTeacherDTO.class);
        dataMap.put("courseTeachers", courseTeacherDTOS);

        return dataMap;
    }
}
